/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pl3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

/**
 *
 * @author Luis Alberto Pérez García <luixal@gmail.com>
 */
public class TokenProviderGenerator {

    public TokenProviderGenerator() {
    }

    static void generateTokenProvider(String inputFilename, String outputFilename, GIC gic) throws FileNotFoundException, IOException {
        BufferedReader in = new BufferedReader(new FileReader(inputFilename));
        BufferedWriter out = new BufferedWriter(new FileWriter(outputFilename));
        // we duplicate content from the input file in the output one:
        String aux = in.readLine();
        while (aux != null) {
            out.write(aux + "\n");
            aux = in.readLine();
        }
        // closing input file:
        in.close();
        // one ended the duplication we add our content for the terminals in the GIC:
        for (String nt:gic.getTerminals()) {
            out.write('"' + nt + '"' + "\t{return yytext();}" + "\n");
        }
        // and we add a few lines needed:
        out.write("\\r|\\n|\\r\\n|\\u2028|\\u2029|\\u000B|\\u000C|\\u0085 {}" + "\n");
        out.write("<<EOF>>\t{return \"$\";}" + "\n");
        out.write(".\t{}" + "\n");
        // closing output file
        out.close();
        // calling jflex to generate the java source file:
        Runtime.getRuntime().exec("jflex -d src/pl3/ newlexical.lex");
    }

    static TokenProvider loadTokenProvider(String filename) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager sfm = compiler.getStandardFileManager(null, null, null);
        String[] opts = new String[] { "-d", "build/classes/pl3/" };

        System.out.println(compiler.getTask(null, sfm, null, Arrays.asList(opts), null, sfm.getJavaFileObjects("src/pl3/" + filename)).call());

        ClassLoader loader = new ClassLoader() {};
        
        File classesDir = new File("build/classes/pl3/");
        URL[] classpath = new URL[] { classesDir.toURI().toURL() };
        URLClassLoader urlClassloader = new URLClassLoader(classpath, loader);
        Class<?> clazz = urlClassloader.loadClass("pl3." + filename.split(".java")[0]);
        TokenProvider loaded = (TokenProvider) clazz.newInstance();
        
        return loaded;
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException, IOException, InterruptedException {
        System.out.println("Trying TokenProviderLoader...");
        GIC gic = new GIC(pl3.io.Input.readFile("gic.lex"));
        System.out.println("GIC Leida: \n" + gic);
        System.out.println("Generando fichero lex desde la plantilla...");
        generateTokenProvider("template.lex", "newlexical.lex", gic);
        System.out.println("Fichero nuevo generado!");
        System.out.println("Compiling...");
        TokenProvider tp = loadTokenProvider("TokenProviderImpl.java");
        tp.yyreset(new java.io.FileReader("input.txt"));
        String aux = tp.yylex();
        while (!aux.equals(Constants.SYMBOLS_EOL)) {
            System.out.println(">>> " + aux);
            aux = tp.yylex();
        }
//        String filename = "TokenProviderImpl.java";
//        System.out.println("Filename: " + filename.split(".java")[0] + ".java");
//        TokenProvider jeje = loadTokenProvider(filename);
//        jeje.nextToken();
    }
    
}
